package com.winit.requirement.web;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.base.bean.ExecuteResult;
import com.winit.common.base.web.BaseController;
import com.winit.commons.util.ObjectToString;
import com.winit.requirement.model.Req;
import com.winit.requirement.model.ReqHistory;
import com.winit.requirement.service.ReqReportFormService;
import com.winit.requirement.service.ReqService;
import com.winit.requirement.manager.BrdRequirementManager;
import com.winit.requirement.model.BrdRequirement;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Api(value = "brd", tags = {"brdRequirement"}, description = "brdRequirement")
@RestController
@RequestMapping("/api/v1/brdRequirement")
public class BrdRequirementController extends BaseController {

    private static Logger log = LoggerFactory.getLogger(BrdRequirementController.class);

    @Autowired
    private BrdRequirementManager brdRequirementManager;

    @Autowired
    private ReqService reqService;

    @Autowired
    private ReqReportFormService reqReportFormService;

    @RequestMapping(value = "/getBrdRequirements", method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "获取brdRequirement")
    @ResponseBody
    public Map getBrdRequirements(@ApiParam(value = "brdId", required = false) @RequestParam(value = "brdId", required = false) String brdId,
                                  @ApiParam(value = "projectPlanId", required = false) @RequestParam(value = "projectPlanId", required = false) String projectPlanId,
                                  @ApiParam(value = "productLineId,产品线", required = false) @RequestParam(value = "productLineId", required = false) String productLineId,
                                  @ApiParam(value = "status,状态", required = false) @RequestParam(value = "status", required = false) String status,
                                  @ApiParam(value = "chargerAccount,PDM负责人", required = false) @RequestParam(value = "chargerAccount", required = false) String chargerAccount,
                                  @ApiParam(value = "keyword,搜索关键字", required = false) @RequestParam(value = "keyword", required = false) String keyword,
                                  @ApiParam(value = "reqId", required = false) @RequestParam(value = "reqId", required = false) String reqId,
                                  @ApiParam(value = "开始时间", required = false) @RequestParam(value = "startDate", required = false) Long startDate,
                                  @ApiParam(value = "是否查看已上线", required = false) @RequestParam(value = "isOnline", required = false) Boolean isOnline,
                                  @ApiParam(value = "withFeatureDesc,是否返回feature快照，0-否，1-是，缺省为1", required = false) @RequestParam(value = "withFeatureDesc", defaultValue = "1") String withFeatureDesc) {
        brdId = StringUtils.isEmpty(brdId) ? null : brdId.trim();
        projectPlanId = StringUtils.isEmpty(projectPlanId) ? null : projectPlanId.trim();
        reqId = StringUtils.isEmpty(reqId) ? null : reqId.trim();
        boolean withFeature = StringUtils.isEmpty(withFeatureDesc) ? true : "0".equals(withFeatureDesc) ? false : true;
        List<?> rs = this.brdRequirementManager.getBrdRequirements(brdId, projectPlanId, reqId, productLineId, status, chargerAccount, keyword, withFeature,startDate,isOnline);
        return this.getRtn(BaseController.REQUEST_SUCCESS, BaseController.REQUEST_SUCCESS_MSG, rs);
    }


    @RequestMapping(value = "/saveBrdRequirement", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "创建/更新brdRequirement")
    @ResponseBody
    public Map saveBrdRequirement(@RequestBody BrdRequirement brdRequirement) {
        if (null == brdRequirement) {
            log.error("no params got...nothing will be done.");
            return this.getRtn(BaseController.REQUEST_ERROR, "no params got...nothing will be done.", null);
        }

        if (null != brdRequirement.getReqIsDel() && (!"0".equals(brdRequirement.getReqIsDel())) && (!"1".equals(brdRequirement.getReqIsDel()))) {
            return this.getRtn(BaseController.REQUEST_ERROR, "param 'reqIsDel' err, only '0' or '1' allowed", null);
        }

        ExecuteResult<BrdRequirement> rs = this.brdRequirementManager.saveBrdRequirement(brdRequirement);
        Object data = rs.getData() == null ? null : rs.getData().getReqId();
        return this.getRtn(rs.getCode(), rs.getDesc(), data);
    }

    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "req上线")
    @RequestMapping(value = "/operateForReqOnline", method = RequestMethod.GET)
    @ResponseBody
    public Map operateForReqOnline(@ApiParam(value = "reqIds，上线的reqIds") @RequestParam(value = "reqIds", required = true) String reqIds) {
        ExecuteResult executeResult = new ExecuteResult();
        if (StringUtils.isEmpty(reqIds)) {
            return this.getRtn(executeResult.getCode(), executeResult.getDesc());
        }
        List<String> reqIdLst = Arrays.asList(reqIds.split(","));
        executeResult = this.brdRequirementManager.operateForReqOnline(reqIdLst);
        return this.getRtn(executeResult.getCode(), executeResult.getDesc(), executeResult.getData());
    }


    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "操作feature与req之间的关系")
    @RequestMapping(value = "/operateRelationBetweenReqAndFeature", method = RequestMethod.GET)
    @ResponseBody
    public Map operateRelationBetweenReqAndFeature(@ApiParam(value = "featureIds，关联的featureIds")@RequestParam(value = "featureIds", required = true)String featureIds,
                                                   @ApiParam(value = "reqId")@RequestParam(value = "reqId", required = true)String reqId,
                                                   @ApiParam(value = "opMode, 1=增加，-1=移除")@RequestParam(value = "opMode", required = true)String opMode) {
        ExecuteResult executeResult = this.brdRequirementManager.operateRelationBetweenReqAndFeature(featureIds, reqId, opMode);
        return this.getRtn(executeResult.getCode(), executeResult.getDesc(), executeResult.getData());
    }


    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "获取req关联的featureId, 按顺序返回")
    @RequestMapping(value = "/getReqFeatureIds", method = RequestMethod.GET)
    @ResponseBody
    public Map getReqFeatureIds(@ApiParam(value = "reqId")@RequestParam(value = "reqId", required = true)String reqId) {
        return this.getRtn("0", "success!", this.brdRequirementManager.getReqFeatureIds(reqId));
    }

    private static class UpdateReqFeatureSequenceParam{
        private String reqId;
        private ArrayList<String> featureIds;

        public String getReqId() {
            return reqId;
        }

        public void setReqId(String reqId) {
            this.reqId = reqId;
        }

        public ArrayList<String> getFeatureIds() {
            return featureIds;
        }

        public void setFeatureIds(ArrayList<String> featureIds) {
            this.featureIds = featureIds;
        }
    }


    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "这个接口仅更新req的feature顺序，而不处理彼此间的关系（如新增/删除）")
    @RequestMapping(value = "/updateReqFeatureSequence", method = RequestMethod.POST)
    @ResponseBody
    public Map updateReqFeatureSequence(@RequestBody UpdateReqFeatureSequenceParam updateReqFeatureSequenceParam) {
        ExecuteResult executeResult = this.brdRequirementManager.updateReqFeatureSequence(updateReqFeatureSequenceParam.getReqId(), updateReqFeatureSequenceParam.getFeatureIds());
        return this.getRtn(executeResult.getCode(), executeResult.getDesc(), executeResult.getData());
    }




    private static class UpdateReqIssueSequenceParam{
        private String reqId;
        private ArrayList<String> issueIds;

        public String getReqId() {
            return reqId;
        }

        public void setReqId(String reqId) {
            this.reqId = reqId;
        }

        public ArrayList<String> getIssueIds() {
            return issueIds;
        }

        public void setIssueIds(ArrayList<String> issueIds) {
            this.issueIds = issueIds;
        }
    }


    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "这个接口仅更新req的issue顺序，而不处理彼此间的关系（如新增/删除）")
    @RequestMapping(value = "/updateReqIssueSequence", method = RequestMethod.POST)
    @ResponseBody
    public Map updateReqIssueSequence(@RequestBody UpdateReqIssueSequenceParam updateReqIssueSequenceParam) {
        ExecuteResult executeResult = this.brdRequirementManager.updateReqIssueSequence(updateReqIssueSequenceParam.getReqId(), updateReqIssueSequenceParam.getIssueIds());
        return this.getRtn(executeResult.getCode(), executeResult.getDesc(), executeResult.getData());
    }


    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "req提交")
    @RequestMapping(value = "/submit", method = RequestMethod.GET)
    @ResponseBody
    public Map submit(@ApiParam(value = "reqId", required = true)@RequestParam(value = "reqId", required = true)String reqId,
                      @ApiParam(value = "tokenId", required = true)@RequestParam(value = "tokenId", required = true)String tokenId){
        ExecuteResult executeResult = this.brdRequirementManager.submit(reqId, tokenId);
        return this.getRtn(executeResult.getCode(), executeResult.getDesc(), executeResult.getData());
    }

    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "查询req的提交历史")
    @RequestMapping(value = "/getReqSubmitHistory", method = RequestMethod.GET)
    @ResponseBody
    public Map getReqSubmitHistory(@ApiParam(value = "reqId", required = true)@RequestParam(value = "reqId", required = true)String reqId){
        List lst = this.brdRequirementManager.getReqSubmitHistory(reqId);
        return this.getRtn(BaseController.REQUEST_SUCCESS, "success!", lst);
    }


    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "查询req最近的提交历史")
    @RequestMapping(value = "/getLatestReqSubmitHistory", method = RequestMethod.GET)
    @ResponseBody
    public Map getLatestReqSubmitHistory(@ApiParam(value = "reqId", required = true)@RequestParam(value = "reqId", required = true)String reqId){
        ReqHistory reqHistory = this.brdRequirementManager.getLatestReqSubmitHistory(reqId);
        return this.getRtn(BaseController.REQUEST_SUCCESS, "success!", reqHistory);
    }

    @RequestMapping(value = "/reqTest", method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "reqTest")
    @ResponseBody
    public Map reqTest(@ApiParam(value = "int pageNum") @RequestParam(value = "pageNum", required = false) int pageNum,
                       @ApiParam(value = "int pageSize") @RequestParam(value = "pageSize", required = false) int pageSize,
                       @ApiParam(value = "reqId") @RequestParam(value = "reqId", required = false) String reqId) {
        List<Req> list = reqService.findAllReq(pageNum, pageSize);
        for (Req req : list)
            System.out.println(ObjectToString.getString(req));

        System.out.println(ObjectToString.getString(reqService.selectByPrimaryKey(reqId)));


        return this.getRtn(BaseController.REQUEST_SUCCESS, BaseController.REQUEST_SUCCESS_MSG,list);
    }

    @RequestMapping(value = "/reqReportForm", method = RequestMethod.POST, consumes = "multipart/form-data")
    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "保存req报表信息，上传文件", consumes = "multipart/form-data")
    @ResponseBody
    public Map uploadFile(@ApiParam(name = "file", allowMultiple = true) @RequestParam("file") MultipartFile file,
                          @ApiParam(name = "reqId", value = "reqId") @RequestParam("reqId") String reqId) throws Exception {
        return this.getRtn("0", "success!", this.reqReportFormService.saveReqReportForm(file, reqId));
    }


    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "下载req报表文件")
    @RequestMapping(value = "/getReqReportFormFile", method = RequestMethod.GET)
    @ResponseBody
    public ExecuteResult<Object> getPrototypeFile(@ApiParam(value = "fileId", required = true) @RequestParam(value = "fileId", required = false) String fileId,
                                                  HttpServletRequest request,
                                                  HttpServletResponse response) throws Exception {
        ExecuteResult<Object> ex = this.reqReportFormService.getPrototype(fileId);
        if("0".equals(ex.getCode())){
            File file = (File) ex.getData();
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            String mimeType = URLConnection.guessContentTypeFromName(file.getName());
            if (mimeType == null) {
                mimeType = "application/octet-stream";
            }
            response.setContentType(mimeType);
            response.setHeader("Content-Disposition", new String(("attachment;fileName=" + file.getName()).getBytes("UTF-8"), "ISO-8859-1"));
            try {
                if (!file.exists()) {
                    ex.setDesc("no file on disk found for this attachment");
                }
                long length = file.length();
                response.setContentLength((int) length);
                InputStream inputStream = new FileInputStream(file);
                OutputStream os = response.getOutputStream();
                byte[] b = new byte[1024];
                int len;
                while ((len = inputStream.read(b)) > 0) {
                    os.write(b, 0, len);
                }
                os.close();
                inputStream.close();
            } catch (Exception e) {
                ex.setDesc(e.getMessage());
            }
        }
        return ex;
    }


    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "查询报表文件列表")
    @RequestMapping(value = "/getReqReportFormList", method = RequestMethod.GET)
    @ResponseBody
    public ExecuteResult getReqReportFormList(@ApiParam(value = "reqId", required = true)@RequestParam(value = "reqId", required = true)String reqId){
        return this.reqReportFormService.getReqReportFormList(reqId);
    }


    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "删除报表文件")
    @RequestMapping(value = "/deleteReqReportForm", method = RequestMethod.GET)
    @ResponseBody
    public ExecuteResult deleteReqReportForm(@ApiParam(value = "fileId", required = true)@RequestParam(value = "fileId", required = true)String fileId){
        ExecuteResult er = this.reqReportFormService.deleteReqReportForm(fileId);
        return er;
    }


    @RequestMapping(value = "/saveBrdRequirementGuideMap", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "创建/更新思维导图")
    @ResponseBody
    public Map saveBrdRequirementGuideMap(@ApiParam(value = "reqId", required = true)@RequestParam(value = "reqId", required = true)String reqId,
                                          @RequestBody JSONObject map) {
        if (null == map) {
            log.error("no params got...nothing will be done.");
            return this.getRtn(BaseController.REQUEST_ERROR, "no params got...nothing will be done.", null);
        }
        ExecuteResult<String> rs = this.brdRequirementManager.saveBrdRequirementGuideMap(reqId,map);
        Object data = rs.getData() == null ? null : rs.getData();
        return this.getRtn(rs.getCode(), rs.getDesc(), data);
    }



    @ResponseStatus(HttpStatus.OK)
    @ApiOperation(value = "获取思维导图")
    @RequestMapping(value = "/getGuideMap", method = RequestMethod.GET)
    @ResponseBody
//    @Cacheable(cacheNames = {"tree_feature"}, key = "#reqId  + '-' +  #sys + '-' + #featureId + '-' + #withChildren + '-' + #withAttrs")
    public Map getGuideMap( @ApiParam(value = "reqId", required = true) @RequestParam(value = "reqId", required = true) String reqId) {
        ExecuteResult executeResult = this.brdRequirementManager.getBrdRequirementGuideMap(reqId);
        return this.getRtn(executeResult.getCode(), executeResult.getMsg(), executeResult.getData());
    }


}
